// resp.hpp
#pragma once
#include <cstddef>
#include <cstdint>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

namespace mini_redis {
// 定义RESP支持的所有数据类型
enum class RespType : char
{
    kSimpleString,    // 简单字符串
    kError,           // 错误
    kInteger,         // 整数
    kBulkString,      // 长字符串
    kArray,           // 数组
    kNull             // 空值
};

// 存储解析后的RESP数据
struct RespValue
{
    RespType    type;    // 数据类型（上面的枚举）
    std::string bulk;    // 用于存储字符串/错误信息/整数文本
    std::vector<RespValue> array;    // 用于存储数组（里面的元素也是RespValue）
};

class RespParser
{
public:
    // 将新收到的字节数据追加到内部缓冲区
    void append(std::string_view data);

    // 尝试从 buffer_ 中解析出一个完整的 RESP
    // 数据单元（比如一个简单字符串、一个整数、一个数组，哪怕数组包含多个元素，也视为
    // “一个完整单元”）。
    std::optional<RespValue> tryParseOne();

    // 与 tryParseOne() 逻辑完全一致，但额外返回解析该 RESP
    // 单元所消耗的原始字节数据（std::string 类型的 raw）。
    std::optional<std::pair<RespValue, std::string>> tryParseOneWithRaw();
private:
    bool parseLine(size_t& pos, std::string& out_line);
    bool parseInteger(size_t& pos, int64_t& out_value);
    bool parseBulkString(size_t& pos, RespValue& out);
    bool parseSimple(size_t& pos, RespType t, RespValue& out);
    bool parseArray(size_t& pos, RespValue& out);

private:
    std::string buffer_;
};

std::string respSimpleString(std::string_view s);
std::string respError(std::string_view s);
std::string respBulk(std::string_view s);
std::string respNullBulk();
std::string respInteger(int64_t v);

}    // namespace mini_redis
